package com.sinosoft.dsp.persistence.hibernate.dao.impl;

import java.sql.SQLException;
import java.util.List;
import java.util.Map;

import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.springframework.orm.hibernate3.HibernateCallback;

import com.sinosoft.dsp.persistence.exception.SinoPersistenceException;
import com.sinosoft.dsp.persistence.hibernate.dao.SearchFormDao;
import com.sinosoft.dsp.platform.components.portal.input.elements.ISinoTagElement;
import com.sinosoft.dsp.system.core.log.Log;

/**
 * 查询表单的DAO
 * 
 * @author PeterPan
 * 
 */
public class SearchFormDaoImpl extends CommonDaoImpl implements SearchFormDao {

	private static final Log log = Log
			.getLog(SearchFormDaoImpl.class.getName());

	/**
	 * 查询表单的分页查询
	 * 
	 * @param hql
	 * @param fields
	 * @param offset
	 * @param pageSize
	 * @return
	 * @throws SinoPersistenceException
	 */
	@Override
	public List<?> findByPageForSearchForm(final String hql,
			final Map<String, ISinoTagElement> fields, final int offset,
			final int pageSize) throws SinoPersistenceException {
		log.debug("find by page for search form: " + hql);
		try {
			List<?> list = this.getHibernateTemplate().executeFind(
					new HibernateCallback() {
						public Object doInHibernate(Session session)
								throws HibernateException, SQLException {
							Query query = session.createQuery(hql);
							if (fields != null) {
								for (Map.Entry<String, ISinoTagElement> entry : fields
										.entrySet()) {
									entry.getValue().setParameter(query,
											entry.getKey());
								}
							}
							List<?> result = query.setFirstResult(offset)
									.setMaxResults(pageSize).list();
							return result;
						}
					});
			return list;
		} catch (RuntimeException re) {
			log.error("find by page for search form failed", re);
			throw new SinoPersistenceException(re);
		}
	}

	/**
	 * 通过查询表单Hql统计总数
	 * 
	 * @param hql
	 * @param fields
	 * @return
	 * @throws SinoPersistenceException
	 */
	@Override
	public Long countForSearchForm(final String hql,
			final Map<String, ISinoTagElement> fields)
			throws SinoPersistenceException {
		log.debug("count for search form: " + hql);
		try {
			List<?> countList = this.getHibernateTemplate().executeFind(
					new HibernateCallback() {
						public Object doInHibernate(Session session)
								throws HibernateException {
							String countHql = "select count(*) from (" + hql
									+ ")";
							Query query = session.createQuery(countHql);
							if (fields != null) {
								for (Map.Entry<String, ISinoTagElement> entry : fields
										.entrySet()) {
									entry.getValue().setParameter(query,
											entry.getKey());
								}
							}
							return query.list();
						}
					});
			Long count = (Long) countList.get(0);
			return count;
		} catch (RuntimeException re) {
			log.error("count for search form failed", re);
			throw new SinoPersistenceException(re);
		}
	}

	/**
	 * 通过查询表单Hql统计总数
	 * 
	 * @param hql
	 * @param fields
	 * @return
	 * @throws SinoPersistenceException
	 */
	@Override
	public Long countForSearchFormByCountSql(final String countHql,
			final Map<String, ISinoTagElement> fields)
			throws SinoPersistenceException {
		log.debug("count for search form: " + countHql);
		try {
			List<?> countList = this.getHibernateTemplate().executeFind(
					new HibernateCallback() {
						public Object doInHibernate(Session session)
								throws HibernateException {
							Query query = session.createQuery(countHql);
							if (fields != null) {
								for (Map.Entry<String, ISinoTagElement> entry : fields
										.entrySet()) {
									entry.getValue().setParameter(query,
											entry.getKey());
								}
							}
							return query.list();
						}
					});
			Long count = (Long) countList.get(0);
			return count;
		} catch (RuntimeException re) {
			log.error("count for search form failed", re);
			throw new SinoPersistenceException(re);
		}
	}

}
